package com.hzit.filter;

import cn.hutool.core.util.StrUtil;
import com.hzit.config.properties.IgnoreWhiteListProperties;
import com.hzit.constant.HzitConstants;
import com.hzit.util.JwtUtil;
import com.hzit.util.ResponseUtil;
import io.jsonwebtoken.Claims;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.util.Map;

/**
 * 类名：
 * 作者：WF
 * 功能：
 */
@Component
public class MyGlobalFilter implements GlobalFilter, Ordered {
	@Autowired
	private IgnoreWhiteListProperties whiteListProperties;
	@Autowired
	private StringRedisTemplate redisTemplate;
	//1. 实现全局过滤逻辑
	@Override
	public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
		//1.1 放行白名单指定的页面
		//① 得到请求
		ServerHttpRequest request = exchange.getRequest();
		//② 得到请求路径
		String path = request.getURI().getPath();
		//③ 判断路径是否在白名单列表中
		if (whiteListProperties.getWhites().contains(path)) {
			return chain.filter(exchange);          // 放行过滤器
		}
		//1.2 根据请求头(Authorization)中是否有指定token，并且来解决token值，找到redis的key，从而根据key是否存在，判断用户是否登录
		String token = getToken(request);
		//1.3 判断token是否存在
		if(StrUtil.isBlank(token)){
			return ResponseUtil.webFluxResponseWriter(exchange.getResponse(),"对不起，Token不存在，请登录！", HttpStatus.UNAUTHORIZED.value());
		}
		//1.4 如果不为null，解析token
		Claims claims = JwtUtil.parseToken(token);
		if(claims == null){
			return ResponseUtil.webFluxResponseWriter(exchange.getResponse(),"对不起，解析token失败！", HttpStatus.UNAUTHORIZED.value());
		}
		//1.5 获取jwtToken值
		Map<String,Object> map = (Map<String, Object>) claims.get(HzitConstants.JWT_TOKEN_KEY);
		if(map == null){
			return ResponseUtil.webFluxResponseWriter(exchange.getResponse(),"对不起，获取JWTToken失败！", HttpStatus.UNAUTHORIZED.value());
		}
		String uuidToken = (String) map.get(HzitConstants.USER_KEY);
		System.out.println("uuidToken = " + uuidToken);
		//1.6 生成redis的key
		String key = getKey(uuidToken);
		//1.7 判断key是否存在
		if (!redisTemplate.hasKey(key)) {
			return ResponseUtil.webFluxResponseWriter(exchange.getResponse(),"对不起，redis没有相关数据，请重新登录！", HttpStatus.UNAUTHORIZED.value());
		}
		return chain.filter(exchange);          // 放行过滤器
	}
	// 生成redis的key
	private String getKey(String uuidToken) {
		return HzitConstants.REDIS_KEY_PREFIX + uuidToken;
	}

	//2. 获取请求头中的token值
	private String getToken(ServerHttpRequest request) {
		//2.1 获取请求头Authorization中的值
		String token = request.getHeaders().getFirst(HzitConstants.REQUEST_HEADER_AUTHORIZATION);
		//2.2 去掉token值中的Bearer 前缀
		return token.replace(HzitConstants.REQUEST_HEADER_BEARER, "");
	}

	//2. 定义过滤器的顺序，值越小顺序越靠前
	@Override
	public int getOrder() {
		return 0;
	}
}
